﻿using System;
using System.Collections.Generic;

namespace UnitTesting.Fixturing
{
	class FreezeValueProvider : IFreezable, IValueProvider, IUnfreezable
	{
		readonly Dictionary<Type, Func<object>> _container;

		internal FreezeValueProvider()
		{
			_container = new Dictionary<Type, Func<object>>();
		}

		public object Create(Type type)
		{
			Ensure.IsNotNull(() => type);
			return !_container.ContainsKey(type)
			       	? NotResolved.Value
			       	: _container[type]();
		}

		public void Freeze<T>(T instance)
		{
			Freeze(() => instance);
		}

		public void Freeze<T>(Func<T> factory)
		{
			Ensure.IsNotNull(() => factory);
			_container[typeof (T)] = () => factory();
		}

		public void UnfreezeAll()
		{
			_container.Clear();
		}

		public void Unfreeze(Type type)
		{
			Ensure.IsNotNull(() => type);
			_container.Remove(type);
		}

		public bool IsFrozen(Type type)
		{
			Ensure.IsNotNull(() => type);
			return _container.ContainsKey(type);
		}
	}
}